// File Name: CustomUIAutomationCPP.cpp

#pragma comment(lib, "User32.lib")

#include "Stdafx.h"
#include "CustomUIAutomationCPP.h"

int UIAutomationCPP::Rotate_PatternID;
int UIAutomationCPP::Rotate_Value_PropertyID;
int UIAutomationCPP::Rotate_IsReadOnly_PropertyID;
int UIAutomationCPP::RotatePatternAvailable_PropertyID;
int UIAutomationCPP::Rotate_Reset_EventID;

namespace UIAutomationCPP
{
	CustomUIAutomationCPP::CustomUIAutomationCPP()
	{
		handlerInfo = RotatePatternHandler();
	}

	CustomUIAutomationCPP::~CustomUIAutomationCPP()
	{
	}

	CustomUIAutomationCPP& CustomUIAutomationCPP::operator =(CustomUIAutomationCPP& rhs)
	{
		if(this != &rhs)
			return rhs;
		return *this;
	}

	int CustomUIAutomationCPP::RegisterRotateProperty()
	{
		HRESULT hr = CoInitialize(NULL);
		if(FAILED(hr))
			return 0;

		IUIAutomationRegistrar *registrar = NULL;
		hr = CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_ALL || CLSCTX_INPROC_SERVER, IID_IUIAutomationRegistrar, (void **)&registrar);
		
		/*CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_INPROC_SERVER, --> CLSCTX has 4 types to use, usually I see inproc_server || 
				IID_IUIAutomationRegistrar, (void **)&pUIARegistrar);*/
		
		/*CoCreateInstance(__uuidof(CUIAutomation), 
            NULL, CLSCTX_INPROC_SERVER, 
            __uuidof(IUIAutomation), 
            (void**)&g_pAutomation);*/

		if (FAILED(hr))
			return E_NOINTERFACE;

		hr = (*registrar).RegisterProperty(propertyInfo, &Rotate_Value_PropertyID);

		(*registrar).Release();
		CoUninitialize();

		return Rotate_Value_PropertyID;
	}

	int CustomUIAutomationCPP::RegisterRotateEvent()
	{
		HRESULT hr = CoInitialize(NULL);
		if(FAILED(hr))
			return 0;

		IUIAutomationRegistrar *registrar = NULL;
		hr = CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_ALL, IID_IUIAutomationRegistrar, (void **)&registrar);

		if (FAILED(hr))
			return E_NOINTERFACE;

		hr = (*registrar).RegisterEvent(eventInfo, &Rotate_Reset_EventID);

		(*registrar).Release();
		CoUninitialize();
		return Rotate_Reset_EventID;
	}
	
	int CustomUIAutomationCPP::RegisterRotatePattern()
	{
		// Initialize COM object
		HRESULT hr = CoInitialize(NULL);
		if(FAILED(hr))
			return 0;

		IUIAutomationRegistrar * registrar;
		hr = CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_INPROC_SERVER, IID_IUIAutomationRegistrar, (void **)&registrar);
		if (FAILED(hr))
			return hr;

		PROPERTYID *propIDs[] = {&(UIAutomationCPP::Rotate_Value_PropertyID), &(UIAutomationCPP::Rotate_IsReadOnly_PropertyID)}; // Array for property IDs
		PROPERTYID ids[2] = {**propIDs, **propIDs + sizeof(PROPERTYID)};

		// Register the control pattern.
		hr = (*registrar).RegisterPattern(&patternInfo,
										&Rotate_PatternID, &RotatePatternAvailable_PropertyID,
										(sizeof(ids))/sizeof(PROPERTYID), ids,
										1, &Rotate_Reset_EventID);
		if(FAILED(hr))
			return hr;
 		else
		{
			*propIDs[0] = ids[0];
			*propIDs[1] = ids[1];
		}

		serve = new ServerSideCustomProvider();
		// Try adding proxy when registering pattern
		proxy = new RotateClientSideCustomProvider();
		
		(*registrar).Release();
		CoUninitialize();
		return Rotate_PatternID;
	}

	LRESULT CustomUIAutomationCPP::CustomControlWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
	{
		switch(uMsg)
		{
			case WM_GETOBJECT:
			{
				ServerSideCustomProvider* pProvider = new ServerSideCustomProvider();
				LRESULT lres = UiaReturnRawElementProvider(hwnd, wParam, lParam, pProvider);
				pProvider->Release();
				return lres;
			}
		}
		return DefWindowProc(hwnd, uMsg, wParam, lParam);
	}
}
